﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using QuickManager.Code.SiteMgr;
using QuickManager.Code.SiteMgr.Model;
using System.Diagnostics;
using System.IO;
using QuickManager.Code.Config;
using QuickManager.Code.Config.Model;
using QuickManager.Code;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading;
using System.Net;

namespace QuickManager.UI.SiteMgr
{
    public partial class SiteEdit : UserControl
    {
        public delegate void AfterSave(SiteInfoModel siteInfo);
        public delegate void StateChanged(bool running);

        public event AfterSave OnSaved;
        public event StateChanged OnStateChanged;

        private UIMode mode;
        private string siteID;
        public SiteEdit(UIMode mode, string siteID)
        {
            InitializeComponent();

            this.Parent = null;

            this.mode = mode;
            this.siteID = siteID;

            //读取注册表
            this.LoadRegisterList();

            //加载数据
            this.SetSiteEdit();

            //其他信息
            this.SetOtherInfo();

            //UI是否设置只读
            if (mode == UIMode.ReadMode)
            {
                foreach (Control cont in this.Controls)
                {
                    this.SetControlsReadOnly(true);
                }
            }
        }

        #region 控件是否只读

        /// <summary>
        /// 设置控件是否只读
        /// </summary>
        /// <param name="readOnly"></param>
        public void SetControlsReadOnly(bool readOnly)
        {
            if (readOnly)
            {
                foreach (Control cont in this.Controls)
                {
                    this.SetChildrenReadOnly(cont);
                }
                //其他特殊控件
                btnSelectSiteDirectory.Enabled = false;
                btnSelectSLNFile.Enabled = false;
                linkUrl.Visible = true;
                linkUrl1.Visible = true;
                btnEdit.Text = "编辑";
            }
            else
            {
                foreach (Control cont in this.Controls)
                {
                    this.SetChildrenEditable(cont);
                }
                //其他特殊控件
                btnSelectSiteDirectory.Enabled = true;
                btnSelectSLNFile.Enabled = true;
                linkUrl.Visible = false;
                linkUrl1.Visible = false;
                btnEdit.Text = "保存";
            }
        }

        void SetChildrenReadOnly(Control control)
        {
            foreach (Control c in control.Controls)
            {
                if (c.Controls.Count > 0)
                {
                    this.SetChildrenReadOnly(c);
                }
                //设置几种控件的只读模式
                if (c is TextBoxBase)
                {
                    (c as TextBoxBase).ReadOnly = true;
                }
                if (c is ComboBox)
                {
                    (c as ComboBox).Enabled = false;
                }
            }
        }

        void SetChildrenEditable(Control control)
        {
            foreach (Control c in control.Controls)
            {
                if (c.Controls.Count > 0)
                {
                    this.SetChildrenEditable(c);
                }
                //设置几种控件的只读模式
                if (c is TextBoxBase)
                {
                    (c as TextBoxBase).ReadOnly = false;
                }
                if (c is ComboBox)
                {
                    (c as ComboBox).Enabled = true;
                }
            }
        }

        #endregion

        #region 读取系统中现有的注册表

        public void LoadRegisterList()
        {
            List<string> list = SiteManager.GetRegisterNameList();
            this.cmbRegisterName.Items.Clear();
            this.cmbRegisterName.Items.AddRange(list.ToArray());
        }

        #endregion

        void SetSiteEdit()
        {
            SiteInfoView view = SiteManager.GetSiteView(this.siteID);
            //网站信息
            this.SiteName.Text = view.SiteInfo.SiteName;
            this.Text = view.SiteInfo.SiteName;
            this.SitePath.Text = view.SiteInfo.LocalPath;
            this.SitePort.Text = view.SiteInfo.Port;
            this.TFSURL.Text = view.SiteInfo.SourcePath;
            this.SLNPath.Text = view.SiteInfo.SlnFile;
            this.cmbSiteNetVersion.SelectedItem = view.SiteInfo.NetVersion;
            this.cmbSitePoolType.SelectedItem = view.SiteInfo.PoolType;
            this.SetDBEdit(view.SiteInfo.RegisterName);

        }

        void SetDBEdit(string registerName)
        {
            //数据库信息
            DBInfoModel dbInfo = SiteManager.GetDBInfo(registerName);
            this.cmbRegisterName.SelectedItem = dbInfo.RegisterName;
            this.DBAddress.Text = dbInfo.Address;
            this.DBName.Text = dbInfo.DBName;
            this.DBUser.Text = dbInfo.UserName;
            this.DBPassword.Text = dbInfo.Passoword == "6.707" ? "95938" : dbInfo.Passoword;

        }

        void SetOtherInfo()
        {
            //站点状态
            this.lblWebState.Text = IISMenager.GetWebSiteState(SiteName.Text);

        }


        private void btnEdit_Click(object sender, EventArgs e)
        {
            if (this.btnEdit.Text == "编辑")
            {
                //允许编辑
                foreach (Control cont in this.Controls)
                {
                    this.SetControlsReadOnly(false);
                }
                this.btnEdit.Text = "保存";
            }
            else
            {
                //保存
                SiteInfoModel oldModel = SiteManager.GetSiteInfo(this.siteID);
                if (oldModel.SiteName != SiteName.Text)
                {
                    //如果站点的名字改了，则重新创建站点
                    SiteManager.CraeteSite(new SiteInfoModel()
                    {
                        SiteID = oldModel.SiteID,
                        SiteName = oldModel.SiteName
                    });
                }
                SiteInfoView siteInfoView = new SiteInfoView()
                {
                    SiteInfo = new SiteInfoModel()
                    {
                        SiteID = this.siteID,
                        GroupID = oldModel.GroupID,
                        SiteName = SiteName.Text,
                        LocalPath = SitePath.Text,
                        SourcePath = TFSURL.Text,
                        SlnFile = SLNPath.Text,
                        Port = SitePort.Text,
                        NetVersion = cmbSiteNetVersion.SelectedItem == null ? "" : cmbSiteNetVersion.SelectedItem.ToString(),
                        PoolType = cmbSitePoolType.SelectedItem == null ? "" : cmbSitePoolType.SelectedItem.ToString(),
                        RegisterName = cmbRegisterName.Text
                    },
                    DBInfo = new DBInfoModel()
                    {
                        RegisterName = cmbRegisterName.Text,
                        Address = DBAddress.Text,
                        DBName = DBName.Text,
                        UserName = DBUser.Text,
                        Passoword = DBPassword.Text == "95938" ? "6.707" : DBPassword.Text
                    },
                    RequireInfo = new LinkRequireModel()
                    {
                        SiteID = this.siteID
                    }
                };

                //提示名称重复
                SiteInfoModel theSameName = SiteManager.GetSiteList().FirstOrDefault(m => string.IsNullOrEmpty(m.SiteName) == false
                && m.SiteName.Equals(siteInfoView.SiteInfo.SiteName, StringComparison.OrdinalIgnoreCase)
                && m.SiteID.Equals(siteInfoView.SiteInfo.SiteID, StringComparison.OrdinalIgnoreCase) == false);
                //端口重复
                SiteInfoModel theSamePort = SiteManager.GetSiteList().FirstOrDefault(m => string.IsNullOrEmpty(m.Port) == false
                && m.Port.Equals(siteInfoView.SiteInfo.Port, StringComparison.OrdinalIgnoreCase)
                && m.SiteID.Equals(siteInfoView.SiteInfo.SiteID, StringComparison.OrdinalIgnoreCase) == false);

                if (theSameName != null)
                {
                    MessageBox.Show("已存在名称为 {0} 的站点，请更换名称。",
                        "提示信息",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                    return;
                }

                if (theSamePort != null)
                {
                    DialogResult dialogResult = MessageBox.Show(string.Format("端口 {0} 已被站点 {1} 占用，确定继续使用？", theSamePort.Port, theSamePort.SiteName),
                        "提示信息",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question);

                    if (dialogResult != DialogResult.Yes)
                    {
                        return;
                    }
                }

                //保存站点信息
                SiteManager.SaveEditSite(siteInfoView);

                //禁止编辑
                foreach (Control cont in this.Controls)
                {
                    this.SetControlsReadOnly(true);
                }
                this.btnEdit.Text = "编辑";
                SiteInfoModel afterModel = SiteManager.GetSiteView(siteInfoView.SiteInfo.SiteID).SiteInfo;
                this.OnSaved(afterModel);   //触发保存事件
            }
        }

        /// <summary>
        /// 选择项目文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectSiteDirectory_Click(object sender, EventArgs e)
        {
            DialogResult result = dialgSelectProject.ShowDialog();
            if (result == DialogResult.OK)
            {
                SitePath.Text = dialgSelectProject.SelectedPath;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {

            DialogResult result = dialgSelectFile.ShowDialog();
            if (result == DialogResult.OK)
            {
                SLNPath.Text = dialgSelectFile.FileName;
            }
        }

        private void linkUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string port = this.SitePort.Text.Trim();
            string url = "http://localhost:" + (string.IsNullOrEmpty(port) ? "80" : port);
            System.Diagnostics.Process.Start("iexplore.exe", url);
        }

        private void linkUrl1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string port = this.SitePort.Text.Trim();
            string url = "http://localhost:" + (string.IsNullOrEmpty(port) ? "80" : port);
            System.Diagnostics.Process.Start(url);
        }

        private void cmbRegisterName_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.SetDBEdit((sender as ComboBox).SelectedItem.ToString());
        }

        private void 去只读ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (string file in Directory.GetFiles(this.SitePath.Text, "*", SearchOption.AllDirectories))
                {
                    File.SetAttributes(file, FileAttributes.Normal);
                }
                MessageBox.Show("去只读完成", "提示信息", MessageBoxButtons.OK);
            }
            catch
            {
                MessageBox.Show("目录不存在或其他错误", "提示信息", MessageBoxButtons.OK);
            }
        }

        #region 编译

        ConfigModel GetBuildConfigInfo()
        {
            if (File.Exists(SLNPath.Text) == false)
            {
                MessageBox.Show("请设置要编译的sln文件位置。", "提示信息", MessageBoxButtons.OK);
                return null;
            }
            string text = File.ReadAllText(SLNPath.Text).Trim();
            VSVersion version = VSVersion.VS2013;

            if (Regex.IsMatch(text, "Format Version 9.00"))
            {
                //vs2005
                version = VSVersion.VS2005;
            }
            else if (Regex.IsMatch(text, "Format Version 10.00"))
            {
                //vs2008
                version = VSVersion.VS2008;
            }
            else if (Regex.IsMatch(text, "Format Version 11.00"))
            {
                //vs2010
                version = VSVersion.VS2010;
            }
            else if (Regex.IsMatch(text, "Format Version 12.00"))
            {
                //vs2012,vs2013
                version = VSVersion.VS2012;
            }
            else
            {
                MessageBox.Show("不支持的VS版本。", "提示信息", MessageBoxButtons.OK);
                return null;
            }

            ConfigModel configInfo = null;
            if (version == VSVersion.VS2012)
            {
                //vs2012和2013选一个，以版本高为主
                ConfigModel c1 = ConfigManager.GetConfig(VSVersion.VS2012.ToString());
                configInfo = ConfigManager.GetConfig(VSVersion.VS2013.ToString());
                if (configInfo == null || string.IsNullOrEmpty(configInfo.ConfigValue))
                {
                    configInfo = c1;
                }
            }
            else
            {
                configInfo = ConfigManager.GetConfig(version.ToString());
            }

            if (configInfo == null || File.Exists(configInfo.ConfigValue + "/devenv.com") == false)
            {
                MessageBox.Show(string.Format("请先配置项目对应版本{0}的编译程序devenv.com所在目录。", version.ToString()), "提示信息", MessageBoxButtons.OK);
                return null;
            }
            return configInfo;
        }

        private void debugToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigModel configInfo = GetBuildConfigInfo();
            if (configInfo == null)
            {
                return;
            }
            try
            {
                VSBuild.Execute(configInfo.ConfigValue, SLNPath.Text, BuildType.Debug);
            }
            catch
            {
            }
        }

        private void releaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigModel configInfo = GetBuildConfigInfo();
            if (configInfo == null)
            {
                return;
            }
            try
            {
                VSBuild.Execute(configInfo.ConfigValue, SLNPath.Text, BuildType.Release);
            }
            catch
            {
            }
        }

        private void 重新编译Debug版本ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigModel configInfo = GetBuildConfigInfo();
            if (configInfo == null)
            {
                return;
            }
            try
            {
                VSBuild.Execute(configInfo.ConfigValue, SLNPath.Text, BuildType.ReDebug);
            }
            catch
            {
            }
        }

        private void 重新编译Release版ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigModel configInfo = GetBuildConfigInfo();
            if (configInfo == null)
            {
                return;
            }
            try
            {
                VSBuild.Execute(configInfo.ConfigValue, SLNPath.Text, BuildType.ReRelease);
            }
            catch
            {
            }
        }

        #endregion

        private void SitePath_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                Process.Start(this.SitePath.Text);
            }
            catch
            {
            }
        }

        private void 回收应用程序池ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                IISMenager.DisposeAppPool(SiteName.Text);
                MessageBox.Show("程序池回收完成", "提示信息", MessageBoxButtons.OK);
            }
            catch
            {
                MessageBox.Show("无法回收，请检查站点是否运行正常。", "提示信息", MessageBoxButtons.OK);
            }
        }

        private void 重启IISToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定重启IIS，本程序不会等待重启完成？", "提示信息", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                IISMenager.ResetIIS();
            }
        }

        private void 启动站点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                IISMenager.StartWebSite(SiteName.Text);
                this.lblWebState.Text = "运行中";
                this.OnStateChanged(true);
            }
            catch
            {
                MessageBox.Show("站点启动异常，请前往IIS进行检查。", "提示信息", MessageBoxButtons.OK);
            }
        }

        private void 停止站点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                IISMenager.StopWebSite(SiteName.Text);
                this.lblWebState.Text = "未运行";
                this.OnStateChanged(false);
            }
            catch
            {
                MessageBox.Show("站点停止异常，请前往IIS进行检查。", "提示信息", MessageBoxButtons.OK);
            }
        }



        private void 推送更新包ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigModel configPackTool = ConfigManager.GetConfig("PackTool");
            if (configPackTool == null
                || string.IsNullOrWhiteSpace(configPackTool.ConfigValue)
                || File.Exists(configPackTool.ConfigValue) == false)
            {
                MessageBox.Show("请先配置推送工具启动位置", "提示信息", MessageBoxButtons.OK);
                return;
            }
            try
            {
                PackToolHelper.Start(this.siteID, configPackTool.ConfigValue);
            }
            catch
            {
                MessageBox.Show("推送工具启动启动失败。", "提示信息", MessageBoxButtons.OK);
            }
        }

        private void SLNPath_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                Process.Start(this.SLNPath.Text);
            }
            catch
            {
            }
        }


    }
}
